package me.mingshan.leetcode;

/**
 * @author hanjuntao
 * @date 2025/10/2 0002
 */
public class L_2331_计算布尔二叉树的值 {

    public static void main(String[] args) {

        TreeNode root = new TreeNode(2);
        TreeNode node1 = new TreeNode(0);
        TreeNode node2 = new TreeNode(3);
        TreeNode node3 = new TreeNode(0);
        TreeNode node4 = new TreeNode(1);

        root.left = node1;
        root.right = node2;
        node2.left = node3;
        node2.right = node4;


        System.out.println(evaluateTree(root));

    }


    /**
     * 从题意可知，这是个完整二叉树，非叶子节点必有两个子节点
     * <p>
     * 只有叶子节点的节点值是0或者1，其他节点都是逻辑运算符
     * <p>
     * 这里可以从下往上进行计算，根节点的值为左右子节点的值进行运算
     *
     *
     * 1. 判断当前节点是否为叶子节点，如果是返回其身值
     * 2. 如果当前节点非叶子节点，那么就必须计算其左右子树的值
     * 3. 递归计算当前左右子树的值
     * 4. 计算完成之后，根据当前节点的值（2或者3），对左右子树的值进行运算（与或运算）
     * 5. 返回计算之后的值
     *
     * @param root
     * @return
     */
    public static boolean evaluateTree(TreeNode root) {
        return evaluateValueTree(root) == 1;
    }

    private static int evaluateValueTree(TreeNode root) {
        // 0,1 代表叶子false,true
        // 2 : 逻辑或
        // 3 : 逻辑与

        TreeNode left = root.left;
        TreeNode right = root.right;

        // 当前root为叶子节点
        if (left == null && right == null) {
            return root.val;
        }

        // 下面是非叶子节点，必有两个子节点
        // 分别获取子节点的值

        int leftValue = evaluateValueTree(left);
        int rightValue = evaluateValueTree(right);

        // 根据当前节点的值进行逻辑运算
        if (root.val == 2) {
            // 逻辑或
            if (leftValue == 0 && rightValue == 0) {
                return 0;
            } else {
                return 1;
            }
        } else {
            // 逻辑与
            if (leftValue == 1 && rightValue == 1) {
                return 1;
            } else {
                return 0;
            }
        }
    }
}
